#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

#define LINE_SEP "\r\n"
#define LINE_SEP_SIZE sizeof(LINE_SEP)

enum
{
    OK = 0,
    MOD_ERR,
    DIV_ERR,
    OP_ERR,
};

// "x op y" ->  "content_len"\r\n"x op y"\r\n
std::string enLength(std::string &text)
{
    std::string send_text = std::to_string(text.size());
    send_text += LINE_SEP;
    send_text += text;
    send_text += LINE_SEP;

    return send_text;
}

// "content_len"\r\n"x op y"\r\n  -> "x op y"
bool deLength(std::string &package, std::string *text)
{
    auto pos = package.find(LINE_SEP);
    if (pos == std::string::npos)
    {
        return false; // 不是一个完整的报文
    }
    int content_len = stoi(package.substr(0, pos));
    *text = package.substr(pos + LINE_SEP_SIZE, content_len);

    return true;
}

class Request
{
public:
    Request()
        : _x(0), _y(0), _op(0)
    {
    }
    Request(int x, int y, char op)
        : _x(x), _y(y), _op(op)
    {
    }

    ~Request()
    {
    }

    // 序列化  对象转成字符串
    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["first"] = _x;
        root["second"] = _y;
        root["operator"] = _op;

        Json::FastWriter Writer;
        *out = Writer.write(root);

        return true;
    }

    // 反序列化  字符串转成对象
    bool deSerialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader Read;
        Read.parse(in, root);
        _x = root["first"].asInt();
        _y = root["second"].asInt();
        _op = root["operator"].asInt();

        return true;
    }

public:
    int _x;
    int _y;
    char _op;
};

// 响应
class Response
{
public:
    Response()
        : _result(0), _resCode(0)
    {
    }
    Response(int result, int resCode)
        : _result(result), _resCode(resCode)
    {
    }

    ~Response()
    {
    }

    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["result"] = _result;
        root["resCode"] = _resCode;
        Json::FastWriter Writer;
        *out = Writer.write(root);

        return true;
    }

    bool deSerialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader Read;
        Read.parse(in, root);
        _result = root["result"].asInt();
        _resCode = root["resCode"].asInt();

        return true;
    }

public:
    int _result;
    int _resCode;
};

// 从一个字符串中获取一个有效的报文  "content_len"\r\n"x op y"\r\n"content_len"\r\n"x op y"\r\n  -> "content_len"\r\n"x op y"\r\n
bool ParseOnePackage(std::string &package, std::string *text)
{
    *text = "";
    auto pos = package.find(LINE_SEP);
    if (pos == std::string::npos)
    {
        return false;
    }
    std::string content = package.substr(0, pos);
    int content_len = stoi(content);
    int total = content.size() + 2 * LINE_SEP_SIZE + content_len;
    if (package.size() < total)
    {
        return false;
    }

    *text = package.substr(0, total);
    // 移除报文
    package.erase(0, total);
    return true;
}